package com.information.manage.basic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.information.manage.basic.mapper.*;
import com.information.manage.basic.model.entity.*;
import com.information.manage.basic.model.query.AddRoleDepartmentQuery;
import com.information.manage.basic.model.query.AddRoleMenuQuery;
import com.information.manage.basic.model.query.FindRolePageQuery;
import com.information.manage.basic.model.query.SysRoleAddQuery;
import com.information.manage.basic.model.vo.RoleDepartmentAuthorityVO;
import com.information.manage.basic.model.vo.RoleMenuAuthorityVO;
import com.information.manage.basic.model.vo.SysRoleIdAndNameVO;
import com.information.manage.basic.model.vo.SysRolePageVO;
import com.information.manage.basic.common.recycling.RecoveryDataOperateManager;
import com.information.manage.basic.common.result.Result;
import com.information.manage.basic.common.result.enums.ResEnum;
import com.information.manage.basic.service.SysRelRoleMenuService;
import com.information.manage.basic.service.SysRoleService;
import com.information.manage.basic.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleDO> implements SysRoleService {

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private RecoveryDataOperateManager recoveryDataOperateManager;

    @Resource
    private SysRelRoleDepartmentMapper sysRelRoleDepartmentMapper;

    @Resource
    private SysRelRoleMenuMapper sysRelRoleMenuMapper;

    @Resource
    private SysRelRoleMenuService sysRelRoleMenuService;

    @Resource
    private SysRelUserRoleMapper sysRelUserRoleMapper;

    @Resource
    private SysRelUserMenuMapper sysRelUserMenuMapper;

    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private SysUserService sysUserService;

    @Override
    public Result<Integer> addRole(SysRoleAddQuery sysRoleAddQuery) {
        if (sysRoleMapper.selectCount(new LambdaQueryWrapper<SysRoleDO>().eq(SysRoleDO::getName, sysRoleAddQuery.getRoleName())) > 0)
            return Result.fail(ResEnum.USER_IS_EXIST.getCode(), "该角色名已存在");
        SysRoleDO sysRoleDO = new SysRoleDO();
        sysRoleDO.setName(sysRoleAddQuery.getRoleName());
        sysRoleDO.setDescription(sysRoleAddQuery.getDescription() == null ? null : sysRoleAddQuery.getDescription());
        sysRoleDO.setCreateTime(LocalDateTime.now());
        sysRoleMapper.insert(sysRoleDO);
        return Result.ok(sysRoleDO.getId());
    }

    @Override
    public Boolean deleteRole(List<Integer> roleIds) {
        recoveryDataOperateManager.deleteData(SysRoleDO.class, roleIds);
        return true;
    }

    @Override
    public Result<Page<SysRolePageVO>> queryPageRole(FindRolePageQuery findRolePageQuery) {
        Page<SysRolePageVO> rolePage = sysRoleMapper.findRolePage(new Page(findRolePageQuery.getCurPage(), findRolePageQuery.getPageSize())
                , findRolePageQuery.getRoleName(), findRolePageQuery.getDescription());
        return Result.ok(rolePage);
    }

    @Override
    public Result<List<SysRoleIdAndNameVO>> queryListRole() {
        List<SysRoleIdAndNameVO> roleIdAndNameList = sysRoleMapper.findRoleIdAndName();
        return Result.ok(roleIdAndNameList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> addRoleDepartment(AddRoleDepartmentQuery addRoleDepartmentQuery) {
        //删除角色的部门权限
        sysRelRoleDepartmentMapper.delete(new LambdaQueryWrapper<SysRelRoleDepartmentDO>()
                .eq(SysRelRoleDepartmentDO::getRoleId, addRoleDepartmentQuery.getRoleId())
                .eq(SysRelRoleDepartmentDO::getTypeCollection, addRoleDepartmentQuery.getTypeCollection()));
        //添加角色的部门权限
        for (Integer departmentId : addRoleDepartmentQuery.getDepartmentIds()) {
            SysRelRoleDepartmentDO sysRelRoleDepartmentDO = new SysRelRoleDepartmentDO();
            sysRelRoleDepartmentDO.setRoleId(addRoleDepartmentQuery.getRoleId());
            sysRelRoleDepartmentDO.setDepartmentId(departmentId);
            sysRelRoleDepartmentDO.setTypeCollection(addRoleDepartmentQuery.getTypeCollection());
            sysRelRoleDepartmentMapper.insert(sysRelRoleDepartmentDO);
        }
        return Result.ok(true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> addRoleMenu(AddRoleMenuQuery addRoleMenuQuery) {
        //删除该角色对应的菜单权限
        sysRelRoleMenuMapper.delete(new LambdaQueryWrapper<SysRelRoleMenuDO>()
                .eq(SysRelRoleMenuDO::getRoleId, addRoleMenuQuery.getRoleId()));
        //添加角色菜单
        List<SysRelRoleMenuDO> list = new ArrayList<>();
        for (Integer menuId : addRoleMenuQuery.getMenuIds()) {
            SysRelRoleMenuDO sysRelRoleMenuDO = new SysRelRoleMenuDO();
            sysRelRoleMenuDO.setRoleId(addRoleMenuQuery.getRoleId());
            sysRelRoleMenuDO.setMenuId(menuId);
            list.add(sysRelRoleMenuDO);
        }
        sysRelRoleMenuService.saveBatch(list);
        //获取该角色绑定的用户
        List<Integer> userIds = sysRelUserRoleMapper.selectObjs(new LambdaQueryWrapper<SysRelUserRoleDO>()
                .select(SysRelUserRoleDO::getUserId)
                .eq(SysRelUserRoleDO::getRoleId, addRoleMenuQuery.getRoleId()))
                .stream().map(it -> (Integer) it).collect(Collectors.toList());
        if (userIds.size() > 0){  //当该角色绑定了用户时
            // 删除用户已有的菜单权限
            sysRelUserMenuMapper.delete(new LambdaQueryWrapper<SysRelUserMenuDO>()
                    .in(SysRelUserMenuDO::getUserId, userIds));
            // 新增修改后的菜单权限
            sysUserService.saveUserMenu(userIds, addRoleMenuQuery.getMenuIds());
        }
        return Result.ok(true);
    }

    @Override
    public Result<Boolean> addAdminMenu(Integer adminRoleId) {
        AddRoleMenuQuery addRoleMenuQuery = new AddRoleMenuQuery();
        addRoleMenuQuery.setRoleId(adminRoleId);
        //获取所有的菜单权限
        List<Integer> menuIds = sysMenuMapper.selectObjs(new LambdaQueryWrapper<SysMenuDO>()
                .select(SysMenuDO::getId)).stream().map(it -> (Integer) it).collect(Collectors.toList());
        if (menuIds.size() > 0){
            addRoleMenuQuery.setMenuIds(menuIds);
            return this.addRoleMenu(addRoleMenuQuery);
        }else {
            return Result.fail("不存在菜单数据");
        }
    }

    @Override
    public Result<List<RoleDepartmentAuthorityVO>> queryDepartment(Integer roleId, Integer typeCollection) {
        List<RoleDepartmentAuthorityVO> roleDepartmentAuthorityVOS = sysRoleMapper.queryDepartmentByRoleId(roleId, typeCollection);
        return Result.ok(roleDepartmentAuthorityVOS);
    }

    @Override
    public Result<List<RoleMenuAuthorityVO>> queryRoleMenu(Integer roleId) {
        List<RoleMenuAuthorityVO> roleDepartmentAuthorityVOS = sysRoleMapper.queryMenuByRoleId(roleId);
        return Result.ok(roleDepartmentAuthorityVOS);
    }
}
